<template>
    <div>
        <search-form :fields="queryFields" @query="reload" v-model="queryParams" class="bg-white p-4 pb-0 mb-4 br-1" />
        <div class="bg-white br-1 p-4">
            <div class="mb-2">
                <el-button type="primary" @click="newRow" v-if="listConfig.withNew != false" icon="plus">新增</el-button>
            </div>

            <el-skeleton :rows="5" v-if="!modelInfo.id" />
            <base-table :fields="fields" :dataSupplier="loadData" ref="tableRef" :pageable="listConfig.pagination" v-else :pageSize="listConfig.pageSize" />
        </div>

        <component :is="'el-' + (formConfig.displayType || 'drawer')" v-model="visible" title="新增">
            <base-form :fields="newFields" v-model="form" labelPosition="top" ref="formRef" />

            <template #footer>
                <el-button type="primary" @click="save">保存</el-button>
                <el-button @click="visible = false">取消</el-button>
            </template>
        </component>
    </div>
</template>
<script setup>
import baseTable from "@/components/base-table/index.vue";
import searchForm from "@/components/search-form.vue";
import https from "@/utils/https";
import { onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import baseForm from "@/components/base-form/index.vue";
import { useRouter } from "vue-router";
import * as _ from "lodash";

const router = useRouter();
const fields = ref([]);
const tableRef = ref();
const visible = ref(false);
const innerFields = ["id", "createTime", "createUser", "updateTime", "updateUser"];
const newFields = ref([]);
const queryFields = ref([]);
const form = ref({});
const formRef = ref();
let primaryField;
const modelInfo = ref({});
const queryParams = ref({});

const modelId = computed(() => {
    return router.currentRoute.value.query.modelId;
});
const listConfig = computed(() => {
    return modelInfo.value.listConfig || {};
});
const formConfig = computed(() => {
    return modelInfo.value.formConfig || {};
});

onMounted(() => {
    https.get("/base/model/published/" + modelId.value).then((resp) => {
        const model = resp;
        modelInfo.value = resp;

        // 处理所使用的字典
        let dictList = resp.dictList;
        let dictMap = {};
        dictList &&
            dictList.forEach((dict) => {
                dictMap[dict.code] = dict.items.map((item) => {
                    return {
                        label: item.name,
                        value: item.value,
                    };
                });
            });

        for (var i in model.fields) {
            const item = model.fields[i];
            if (item.primaryKey) {
                primaryField = item.code;
                break;
            }
        }
        if (!primaryField) {
            primaryField = "id";
        }

        let sourceFields = model.listFields || model.fields;
        sourceFields.forEach((field) => {
            const listField = {
                label: field.name,
                prop: field.code,
                width: field.width,
            };

            let dictCode = field.dictCode;
            let options = dictMap[dictCode];

            if (options) {
                // 处理列表字段转换
                listField.converter = (val) => {
                    for (var i in options) {
                        let option = options[i];
                        if (option.value == val) {
                            return option.label;
                        }
                    }

                    return val;
                };
            }

            // 处理列表字段
            !field.hide && fields.value.push(listField);

            // 处理查询字段
            if (field.asQuery) {
                let item = {
                    label: field.name,
                    prop: field.code,
                    placeholder: field.queryCmp == "select" ? "请选择..." : "请输入...",
                    queryType: field.queryType,
                    options,
                };

                // 查询类型
                let queryCmp = field.queryCmp;
                if (queryCmp == "datePicker") {
                    item.type = "datePicker";
                } else if (queryCmp == "dateRange") {
                    item.type = "datePicker";
                    item.dateType = "daterange";
                } else {
                    item.type = field.queryCmp;
                }

                queryFields.value.push(item);
            }
        });

        // 处理表单字段
        if (model.formFields && model.formFields.length) {
            model.formFields.forEach((field) => {
                if (field.hide) {
                    return;
                }

                const dictCode = field.dictCode;
                const options = dictMap[dictCode];

                // 有配置好的表单字段
                const code = field.code;
                // 添加到新增记录中
                let cmp = field.cmp;
                let type;
                let format;
                let dateType;
                switch (cmp) {
                    case "number": {
                        type = "number";
                        break;
                    }
                    case "radio": {
                        type = "radioGroup";
                        break;
                    }
                    case "checkbox": {
                        type = "checkbox";
                        break;
                    }
                    case "select": {
                        type = "select";
                        break;
                    }
                    case "textarea": {
                        type = "textarea";
                        break;
                    }
                    case "switch": {
                        type = "switch";
                        break;
                    }
                    case "datePicker": {
                        type = "datePicker";
                        format = "YYYY-MM-DD";
                        break;
                    }
                    case "dateTime": {
                        type = "datePicker";
                        dateType = "datetime";
                        format = "YYYY-MM-DD HH:mm:ss";
                        break;
                    }
                    case "time": {
                        type = "timePicker";
                        format = "HH:mm:ss";
                        break;
                    }
                    default:
                }

                newFields.value.push({
                    label: field.name,
                    prop: code,
                    type: type,
                    format: format,
                    dateType: dateType,
                    required: !field.nullable,
                    options,
                    default: field.defaultValue,
                });
            });
        } else {
            model.fields.forEach((field) => {
                const dictCode = field.dictCode;
                const options = dictMap[dictCode];

                const code = field.code;
                if (innerFields.includes(code)) {
                    return;
                }
                let dataType = field.dataType;
                let type;
                let format;
                let dateType;
                if (dataType == "date") {
                    type = "datePicker";
                    format = "YYYY-MM-DD";
                    dateType = "date";
                } else if (dataType == "datetime") {
                    type = "datePicker";
                    format = "YYYY-MM-DD HH:mm:ss";
                    dateType = "datetime";
                } else if (dataType == "time") {
                    type = "timePicker";
                    format = "HH:mm:ss";
                }

                newFields.value.push({
                    label: field.name,
                    prop: code,
                    type: type,
                    format: format,
                    dateType: dateType,
                    required: !field.nullable,
                    options,
                    default: field.defaultValue,
                });
            });
        }

        // 增加操作按钮
        if (listConfig.value.withDelete != false) {
            const buttons = [];
            if (listConfig.value.withEdit) {
                buttons.push({ label: "编辑", type: "primary", action: goEdit });
            }
            if (listConfig.value.withDelete) {
                buttons.push({ label: "删除", type: "danger", action: deleteRow });
            }

            fields.value.push({
                label: "操作",
                type: "operations",
                width: "100px",
                buttons,
            });
        }
    });
});

function reload() {
    tableRef.value.reload();
}

function loadData(params) {
    let finalParams = _.cloneDeep(params);

    // 补充查询条件
    let filters = [];
    queryFields.value.forEach((field) => {
        let code = field.prop;
        let value = queryParams.value[code];
        if (!value && value != 0) {
            return;
        }

        // 主要是处理日期区间
        if (field.dateType == "daterange") {
            filters.push({
                key: code,
                op: "between",
                value: value[0],
                value1: value[1] + " 23:59:59",
            });
        } else {
            filters.push({
                key: code,
                op: field.queryType || "eq",
                value,
            });
        }
    });
    finalParams.filters = filters;

    return https.post(`/base/model/data/${modelId.value}/page-query`, finalParams);
}

function newRow() {
    form.value = {};
    visible.value = true;
}

function save() {
    formRef.value.validate((resp) => {
        if (!resp) {
            return;
        }

        https.post(`/base/model/data/${modelId.value}/save`, form.value).then((resp) => {
            visible.value = false;
            ElMessage.success("操作成功");
            reload();
        });
    });
}

function goEdit(row) {
    form.value = _.cloneDeep(row);
    visible.value = true;
}

function deleteRow(row) {
    let primaryCode = primaryField.value || "id";
    ElMessageBox.confirm("确定删除当前记录？").then(() => {
        https.del(`/base/model/data/${modelId.value}/delete?${primaryCode}=${row[primaryCode]}`).then(() => {
            ElMessage.success("删除成功");
            tableRef.value.reload();
        });
    });
}
</script>

<style lang="scss" scoped></style>
